/**
 * @file device.h 设备模块的头文件
 *  device向上(menu)提供设备模块的结构定义和增删查改功能
 *  向下(dlist)调用链表的具体函数来实现这些功能
 *  包含: 
 * 1. 设备结构定义
 * 2. dlist用到的各种具体的比较函数/显示函数等
 * 3. 提供给上层的操作功能函数
 * @author pzk (1528089905@qq.com)
 * @brief 
 * @version 1.0
 * @date 2025-8-4
 * 
 * @copyright copyright (c) 2025
 */

#ifndef DEVICE_H
#define DEVICE_H

#include "dlist.h"
#include "comm.h"

//设备结构体
typedef struct device
{
    //自动维护的数据，用户不能修改
    int dev_id;         //设备号:10001开始，不会重复
    int dev_order;      //设备序号
    int dev_status;    //设备工作状态：0-off  1-on
    float cur_value;   //当前值
    //用户可以修改的数据
    char dev_name[32];  //设备名称
    char dev_type[32];  //设备类型
    char dev_ip[16];    //设备地址
    float power_ele;    //设备功率
    char dev_desc[128]; //设备描述
}device_t;

//更新函数指针
typedef int (*updatefun_t)(void *data1,const void *data2);

/** 
 * @brief  ID生成器，新建设备时+1,全局变量dev_id_min  
 * 
 */
int generate_id();


/** 
 * @brief  从文件中加载设备列表，形成链表
 * 
 * 
 * @return node_t*  链表头指针
 */
node_t *load_devices();


/** 
 * @brief:  将当前链表数据保存到文件中
 * 
 * @param: 
 *      @head  链表头指针
 * @return: int  成功返回0，失败返回-1
 */
int save_devices(node_t *head);


/** 
 * @brief： 输入数值添加设备
 * 
 * @param:
 * 		@head    链表头指针
 *      @newdev  新设备数据
 * @return int  成功返回0，失败返回-1
 */
int add_dev(node_t *head,const device_t *newdev);


/** 
 * @brief  查找设备，可根据ID，设备名，设备类型
 * 返回的是一个新的链表, 使用完毕需要删除
 * 
 * @param 
 *      @head      链表头指针
 *      @cmpfun    查找方式
 *      @dev       查找数据
 * @return node_t*  查找到的节点新链表
 */
node_t *find_dev(node_t *head, cmpfun_t cmpfun, const device_t *dev);


/** 
 * @brief  比较函数，根据ID，设备名，设备类型
 * 
 * @param 
 *      @data1 数据1
 *      @data2 数据2
 * @return int 比较结果，0相同
 */
int cmpDev_ID(const void *data1, const void *data2);
int cmpDev_Name(const void *data1,const void *data2);
int cmpDev_Type(const void *data1,const void *data2);
int cmpDev_Status(const void *data1,const void *data2);

/** 
 * @brief  删除设备,可根据ID，设备名，设备类型，删除所有符合的
 * 
 * @param 
 * 		@head      链表头指针
 * 		@cmpfun    查找方式
 * 		@dev       查找的数据
 * @return int 返回0删除成功，-1删除失败(无设备)
 */
int del_dev(node_t *head, cmpfun_t cmpfun, const device_t *dev);


/** 
 * @brief  更新设备，根据id查找设备，更新方式1设备名，方式2设备类型
 * 
 * @param 
 * 		@head         链表头指针
 * 		@id           设备id
 * 		@updateMode   更新方式
 * 		@updatedev    新的数据
 * @return node_t*    更新之后的链表
 */
node_t *update_dev(node_t *head, int id, int updateMode, const device_t *updatedev);


/** 
 * @brief  排序(选择排序法)，根据比较方式(ID,设备名,设备类型)排序
 * 
 * @param 
 * 		@head     链表头指针
 * 		@cmpfun   比较方式
 * @return int     成功返回0，失败返回-1
 */
int sort_dev(node_t *head,cmpfun_t cmpfun);


/** 
 * @brief  清空设备，二次确认
 * 
 * @param 
 * 		@head      链表头指针
 *
 * @return 0清空成功，-1失败
 */
int clear_dev(node_t *head);


/** 
 * @brief  显示设备
 * 
 * @param 
 * 		@head      链表头指针
 * 		@showfun   显示方式
 */
void show_dev(node_t *head,showfun_t showfun);


/** 
 * @brief  显示函数，格式显示所有数据
 * 
 * @param 
 *      @data 数据
 *
 */
void showDev_All(const void *data);


/** 
 * @brief  开关设备
 * 
 * @param 
 * 		@head       链表头指针
 *      @to_status  需要的状态
 *      @id         设备id
 *
 * @return 0清空成功，-1失败
 */
node_t *control_dev(node_t *head,int to_status,int id);

#endif //DEVICE_H
